<?php

class Thumb_Plugins_Smart extends ThumbPlugin
{
	public function convert ($src_im, $thumb, &$thumb_out=NULL)
	/**
	 * Создать предпросмотр для картинки.
	 *
	 * @param mixed $src_im исходная картинка (нечто, возвращаемое imagecreate*())
	 * @param array $thumb array (
	 *                            'h' => -- высота картинки (в пикселях) :: integer
	 *                            'w' => -- шинина картинки (в пикселях) :: integer
	 *                            );
	 *                            любой из ключей может отсутствовать, тогда для его вычисления
	 *                            применится умная эвристика 8)
	 * @param array& $thumb_out то же что $thumb заполняется недостающими параметрами
	 * @access public
	 * @return resource $dst_im
	 */
	{
		$width  = imagesx($src_im);
		$height = imagesy($src_im);
		$src_im_type = $thumb['type'];

		// перед масштабированием нужно проверить если одна сторона больше чем в два раза чем другая то сохранить этот признак
		$one_side_longer_than_other = false;
		if (($width > 2*$height) || ($height > 2*$width)) $one_side_longer_than_other = true;

		// поехали

		// проверим не меньше ли оригинал чем тумбнейл
		if (($thumb['w']>$width)&&($thumb['h']>$height)) {
			/*===== оригинал меньше чем тумбнейл =====*/
			// 1. оригинал меньше чем тумбнейл - положить картинку в центр на прозрачный фон

			// координаты левой верхней точки
			$lu_x = $thumb['w']/2 - $width/2;
			$lu_y = $thumb['h']/2 - $height/2;

			$dst_im = imagecreatetruecolor($thumb['w'], $thumb['h']);
			$thumb_out['type'] = in_array($thumb['type'], array(IMAGETYPE_PNG, IMAGETYPE_GIF)) ? $thumb['type'] : IMAGETYPE_PNG;
			ImageUtils::copy_transparency($dst_im, $src_im);

			imagecopy($dst_im, $src_im, ceil($lu_x), ceil($lu_y), 0, 0, $width, $height);
			$new_width = $thumb['w'];
			$new_height = $thumb['h'];

			/*===== оригинал меньше чем тумбнейл =====*/
		} elseif ($thumb['w'] && $thumb['h']) {
			/*===== жесткие размеры по обоим разрешениям =====*/

			// если у нас установлен $one_side_longer_than_other,
			// тогда масштабируем так чтобы влезло большее разрешение полностью ("полоска"),
			// если нет то вырезаем кусок по центру

			if ($one_side_longer_than_other) {
				// определить большее измерение оригинала и смасштабировать по нему

				if ($width > $height) { // 2. ширина больше высоты
					$new_width = $thumb['w'];
					$new_height = $thumb['w']/$width * $height;

					// координаты верхней левой точки
					$lu_x = 0;
					$lu_y = $thumb['h']/2 - $new_height/2;
				} else { // 3. высота больше ширины
					$new_width = $thumb['h']/$height * $width;
					$new_height = $thumb['h'];

					//	координаты верхей левой точки
					$lu_x = $thumb['w']/2 - $new_width/2;
					$lu_y = 0;
				}

				$dst_im = imagecreatetruecolor($thumb['w'], $thumb['h']);
				$thumb_out['type'] = in_array($thumb['type'], array(IMAGETYPE_PNG, IMAGETYPE_GIF)) ? $thumb['type'] : IMAGETYPE_PNG;
				ImageUtils::copy_transparency($dst_im, $src_im);

				imagecopyresampled($dst_im, $src_im, ceil($lu_x), ceil($lu_y), 0, 0, $new_width, $new_height, $width, $height);
			} else { // вырезать кусок по центру
				// сюда мы можем попасть только в двух случаях: одно из измерений оригинала меньше тумбнейла или
				// оба измерения оригинала больше

				$lu_x = 0; $lu_y = 0; $new_width = 0; $new_height = 0;

				if ($width < $thumb['w']) { // 4. ширина оригинала меньше ширины тумбнейла
					// тогда надо увеличить оригинал пропорционально до ширины тумбнейла
					// и обрезать
					$new_width = $thumb['w'];
					$new_height = $height * $new_width/$width;

					$lu_y = $new_height/2 - $thumb['h']/2;

				} elseif ($height < $thumb['h']) { // 5. высота оригинала меньше чем высота тумбнейла
					// тогда надо увеличить оригинал пропорционально до высоты тумбнейла
					$new_height = $thumb['h'];
					$new_width = $width * $new_height/$height;

					$lu_x = $new_width/2 - $thumb['w']/2;

				} else { // оба измерения больше аналогичных измерений тумбнейла
					// нужно выбрать меньшее измерение и смасштабировать по нему пропорционально
					if ($width > $height) { // 6. ширина больше высоты
						$new_height = $thumb['h'];
						$new_width = $width * $new_height/$height;

						$lu_x = $new_width/2 - $thumb['w']/2;
					} else { // 7. высота больше ширины или равна
						$new_width = $thumb['w'];
						$new_height = $height * $thumb['w']/$width;

						$lu_y = $new_height/2 - $thumb['h']/2;

					}

				}

				$thumb_out['type'] = in_array($thumb['type'], array(IMAGETYPE_PNG, IMAGETYPE_GIF)) ? $thumb['type'] : IMAGETYPE_PNG;
				// увеличим
				$image_tmp = imagecreatetruecolor($new_width, $new_height);
				ImageUtils::copy_transparency($image_tmp, $src_im);
				// копия
				imagecopyresampled($image_tmp, $src_im, 0, 0, 0, 0, $new_width, $new_height, $width, $height);

				$dst_im = imagecreatetruecolor($thumb['w'], $thumb['h']);
				ImageUtils::copy_transparency($dst_im, $image_tmp);
				// обрежем
				// HACK : 2007-11-28 : lucky
				// в оригинале было
				// imagecopy($dst_im, $image_tmp, 0, 0, ceil($lu_x), ceil($lu_y), $new_width, $new_height);
				imagecopy($dst_im, $image_tmp, -ceil($lu_x), ceil($lu_y), 0, 0, $new_width, $new_height);
			}

			/*===== жесткие размеры по обоим разрешениям =====*/
		} elseif ($thumb['w'] || $thumb['h']) {
			/*===== жесткое ограничение только по одному размеру =====*/
			// если у нас установлен $one_side_longer_than_other,
			// то сохраним полоску руководствуясь "самым большим разрешением для тумбнейла" $this->max_size
			// если нет - то просто масштабируем по тому разрешению по которому задано

			if (isset($thumb['w'])) { // по ширине?
				$thumb['h'] = $this->max_size;
			} else { // ан нет - по высоте..
				$thumb['w'] = $this->max_size;
			}

			if ($one_side_longer_than_other) {
				// сделать полоску, аналогично 2. или 3. только по высоте взять за размер тумбнейла $this->max_size

				if ($width > $height) { // 2. ширина больше высоты
					$new_width = $thumb['w'];
					$new_height = $thumb['w'] / $width * $height;

					// координаты верхней левой точки
					$lu_x = 0;
					$lu_y = $thumb['h']/2 - $new_height/2;
				} else { // 3. высота больше ширины
					$new_width = $thumb['h'] / $height * $width;
					$new_height = $thumb['h'];

					//	координаты верхей левой точки
					$lu_x = $thumb['w']/2 - $new_width/2;
					$lu_y = 0;
				}

			} else {
				// просто масштабируем по ширине, без обрезания
				$new_width = $thumb['w'];
				$new_height = $thumb['w'] / $width * $height;
				$lu_x = 0;
				$lu_y = 0;

			}
			
			$thumb_out['type'] = in_array($thumb['type'], array(IMAGETYPE_PNG, IMAGETYPE_GIF)) ? $thumb['type'] : IMAGETYPE_PNG;
			// увеличим
			$image_tmp = imagecreatetruecolor($width, $height);
			ImageUtils::copy_transparency($image_tmp, $src_im);
			// копия
			imagecopy($image_tmp, $src_im, 0, 0, 0, 0, $width, $height);

			$dst_im = imagecreatetruecolor($thumb['w'], $thumb['h']);
			ImageUtils::copy_transparency($dst_im, $image_tmp);
			imagecopyresampled($dst_im, $image_tmp, ceil($lu_x), ceil($lu_y), 0, 0, ceil($new_width), ceil($new_height), $width, $height);
			
			/*===== жесткое ограничение только по одному размеру =====*/
		}

		$thumb_out['w'] = $new_width;
		$thumb_out['h'] = $new_height;

		return $dst_im;
	} // end of function convert
}

